﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using IndicoInterface;
using DTBuilderLib;
using System.IO;
using IndicoInterface.SimpleAgendaDataModel;
using DTBuilderLib.VisualHierarchyClasses;
using System.Drawing;

namespace t_DTBuilderLib
{
    /// <summary>
    /// Summary description for t_ZeepZoomBuilder
    /// </summary>
    [TestClass]
    public class t_DeepZoomBuilder
    {
        public t_DeepZoomBuilder()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void DeepZoomBuilderCTor()
        {
            DeepZoomBuilder dz = new DeepZoomBuilder();
            dz.BuildDirectory = "c:\\root";
            Assert.IsTrue(dz.BuildDirectory == "c:\\root", "Failed to set BuildDirectory");
        }

#if false
        [TestMethod]
        public void DeepZoomBuildXMLForSingleTalk()
        {
            /// Render a small meeting that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            var talks = from s in data.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL.Length != 0
                        select t;
            var talk = talks.First();

            JPEGRender r = new JPEGRender();
            var slides = r.RenderTalk(talk.SlideURL);

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForTalkSlides(slides);

            DeepZoomBuilder_Accessor dzbld = new DeepZoomBuilder_Accessor();
            FileInfo renderedSlides = dzbld.RenderVisualToXML("TestTalk1", v);
            Assert.IsTrue(renderedSlides.Exists, "Output XML file does not exist!");
        }
#endif

        [TestMethod]
        public void DeepZoomRenderSimpleImage()
        {
            VisualBitmapImage bm = new VisualBitmapImage(11.0F, 8.5F, 100, Color.Red);
            DeepZoomBuilder bld = new DeepZoomBuilder();
            DirectoryInfo d = new DirectoryInfo(".\\DeepZoomRenderSimpleImage");
            bld.BuildDirectory = d.FullName;
            if (!d.Exists)
            {
                d.Create();
            }
            DirectoryInfo renderedDir = bld.RenderVisual("DeepZoomRenderSimpleImage", bm);

            Assert.IsTrue(renderedDir.Exists, "Output directory does not exist!");
            Assert.IsTrue(File.Exists(renderedDir.FullName + "\\token.txt"), "Token file does not exist!");
            Assert.IsTrue(File.Exists(renderedDir.FullName + "\\DeepZoomRenderSimpleImage.xml"), "Output xml file does not exist");
        }

        [TestMethod]
        public void TestRenderNullImage()
        {
            DeepZoomBuilder bld = new DeepZoomBuilder();
            DirectoryInfo d = new DirectoryInfo(".\\TestRenderNullImage");
            bld.BuildDirectory = d.FullName;
            if (!d.Exists)
            {
                d.Create();
            }
            DirectoryInfo renderedDir = bld.RenderVisual("TestRenderNullImage", null);
        }

        [TestMethod]
        public void DeepZoomRenderTokenTest()
        {
            /// Make sure the token file works right!
            VisualBitmapImage bm = new VisualBitmapImage(11.0F, 8.5F, 100, Color.Red);
            DeepZoomBuilder bld = new DeepZoomBuilder();
            DirectoryInfo d = new DirectoryInfo(".\\renders");
            bld.BuildDirectory = d.FullName;
            if (!d.Exists)
            {
                d.Create();
            }

            string talkName = "DeepZoomRenderTokenTest";
            Assert.IsFalse(bld.MeetingAlreadyRendered(talkName), "Meeting shouldn't be marked as rendered!");
            DirectoryInfo renderedDir = bld.RenderVisual(talkName, bm);
            Assert.IsTrue(bld.MeetingAlreadyRendered(talkName), "Meeting should be marked as rendered now!");

            /// Now that is rendered, see that the token is "set" internally...

            bld.ClearToken(talkName);
            Assert.IsFalse(bld.MeetingAlreadyRendered(talkName), "Meeting shouldn't be marked as rendered!");

            bld.SetToken(talkName);
            Assert.IsTrue(bld.MeetingAlreadyRendered(talkName), "Meeting should be marked as rendered after token was cleared!");
        }

        [TestMethod]
        public void DeepZoomRenderCrash()
        {
            DirectoryInfo renderedDir = null;
            try
            {
                VisualBitmapImage bm = new VisualBitmapImage(1.0F, 1.0F, 16000, Color.Red);
                DeepZoomBuilder bld = new DeepZoomBuilder();
                renderedDir = bld.RenderVisual("DeepZoomRenderCrash", bm);
                Assert.Fail("SparseImageTool did not crash - can't complete test!");
            }
            catch
            {
            }
        }

        [TestMethod]
        public void TestRenderVisualsAsCollections()
        {
            DirectoryInfo curDir = new DirectoryInfo(".\\TestRenderVisualsAsCollections");
            DirectoryInfo imageDir = new DirectoryInfo(curDir.FullName + "\\images");

            if (!imageDir.Exists)
            {
                imageDir.Create();
            }

            VisualHolder master = new VisualHolder();
            for (int i = 0; i < 3; i++)
            {
                VisualHolder h = new VisualHolder();
                for (int j = 0; j < 3; j++)
                {
                    VisualBitmapImage b = new VisualBitmapImage(1.0, 1.0, 600, Color.Red);
                    b.ImageWritingDirectory = imageDir;
                    b.XPosition = j * 1.1;
                    h.AddImage(b);
                }

                h.XPosition = i * 4.5;
                h.IsCompositionUnit = true;
                h.ShortName = "bogus_" + i.ToString();
                h.Title = "Really Darn Bogus";
                master.AddImage(h);
            }
            DeepZoomBuilder bld = new DeepZoomBuilder();
            bld.BuildDirectory = curDir.FullName;
            DirectoryInfo renderedDir = bld.RenderVisual("TestRenderVisualsAsCollections", master);
            Assert.IsTrue (File.Exists(renderedDir.FullName + "\\token.txt"), "Could not find token file");

            ///
            /// Now, see if the sub-token files are there!
            /// 

            Assert.IsTrue(File.Exists(renderedDir.FullName + "\\sc\\bogus_0.xml"), "Could not find one of the sub-file files");

            ///
            /// Is the meeting meta data thing there?
            /// 

            Assert.IsTrue(File.Exists(renderedDir.FullName + "\\meetingMetadata.xml"), "Meeting meta data is missing");
        }

#if false
        [TestMethod]
        public void DeepZoomRenderTalkSlides()
        {
            /// Render a the slides from a talk we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            var talks = from s in data.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL.Length != 0
                        select t;
            var talk = talks.First();

            JPEGRender r = new JPEGRender();
            var slides = r.RenderTalk(talk.SlideURL);

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForTalkSlides(slides);

            DeepZoomBuilder dzbld = new DeepZoomBuilder();
            DirectoryInfo renderedSlides = dzbld.RenderVisual("TestTalk1", v);

            Assert.IsTrue(renderedSlides.Exists, "Output directory does not exist");
            Assert.IsTrue(File.Exists(renderedSlides.FullName + "\\TestTalk1.xml"), "output bin file does not exist");
            Assert.IsTrue(File.Exists(renderedSlides.FullName + "\\token.txt"), "Output token does not exist");
        }
#endif

#if false
        [TestMethod]
        public void DeepZoomRenderATalk()
        {
            /// Render a talk that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            var talks = from s in data.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL.Length != 0
                        select t;
            var talk = talks.First();

            JPEGRender r = new JPEGRender();
            var slides = r.RenderTalk(talk.SlideURL);

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForATalk(talk.Title, "Author - time (15 minutes)", slides);

            DeepZoomBuilder dzbld = new DeepZoomBuilder();
            DirectoryInfo renderedSlides = dzbld.RenderVisual("DeepZoomRenderATalk", v);

            Assert.IsTrue(renderedSlides.Exists, "Output directory does not exist");
            Assert.IsTrue(File.Exists(renderedSlides.FullName + "\\DeepZoomRenderATalk\\info.bin"), "output bin file does not exist");
            Assert.IsTrue(File.Exists(renderedSlides.FullName + "\\token.txt"), "Output token does not exist");
        }
#endif

#if false
        [TestMethod]
        public void DeepZoomRenderSession()
        {
            /// Render a session that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            Assert.IsTrue(data.Sessions.Length == 1, "More than one session for this test -- that is bad!");

            JPEGRender r = new JPEGRender();
            var renderedSlides = r.RenderMeeting(data);

            var talks = from s in data.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL.Length != 0
                        select t;

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForASession(data.Title, data.StartDate, data.EndDate, talks.ToArray(), renderedSlides);
            DeepZoomBuilder dzbld = new DeepZoomBuilder();
            DirectoryInfo output = dzbld.RenderVisual("DeepZoomRenderSession", v);

            Assert.IsTrue(output.Exists, "Output directory does not exist");
            Assert.IsTrue(File.Exists(output.FullName + "\\DeepZoomRenderSession\\info.bin"), "output bin file does not exist");
            Assert.IsTrue(File.Exists(output.FullName + "\\token.txt"), "Output token does not exist");
        }

        [TestMethod]
        public void DeepZoomRenderBigMeeting()
        {
            /// Render a session that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(14475);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            Assert.IsTrue(data.Sessions.Length > 1, "More than one session for this test -- that is bad!");

            JPEGRender r = new JPEGRender();
            var renderedSlides = r.RenderMeeting(data);

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForAMeeting(data, renderedSlides);

            DeepZoomBuilder dzbld = new DeepZoomBuilder();
            DirectoryInfo output = dzbld.RenderVisual("DeepZoomRenderBigMeeting", v);

            Assert.IsTrue(output.Exists, "Output directory does not exist");
            Assert.IsTrue(File.Exists(output.FullName + "\\DeepZoomRenderSession\\info.bin"), "output bin file does not exist");
            Assert.IsTrue(File.Exists(output.FullName + "\\token.txt"), "Output token does not exist");
        }
#endif

#if false
        [TestMethod]
        public void DeepZoomOneTalk()
        {
            /// Attemt to deep zoom one talk
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var meeting = jd.DownloadMeeting(a.GetNormalizedConferenceData());            
            JPEGRender rend = new JPEGRender();
            var talkjpegs = rend.RenderMeeting(meeting);

            DeepZoomBuilder bld = new DeepZoomBuilder();
            var talks = from s in meeting.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL != ""
                        select t;

            var atalk = talks.First();

            FileInfo infoFile = bld.RenderTalk("TalkTest", talkjpegs[atalk]);

            /// See if the files were created and all are there...
            Assert.IsTrue(infoFile.Exists, "Output Scene info file does not exist!");
            Assert.IsTrue(File.Exists(infoFile.DirectoryName + "\\TalkTest\\items.xml"), "The info.xml file does not exist!");
            Assert.IsTrue(File.Exists(infoFile.DirectoryName + "\\TalkTest\\items.bin"), "The info.bin file does not exist!");

            /// See if the token file indicating this job finished w/out error is there.
            /// This isn't an external interface, but it is in that it makes sure we don't have to re-run things.
            Assert.IsTrue(File.Exists(infoFile.DirectoryName + "\\TalkTest-token.txt"), "Token indicating job well done does not exist");
        }

        [TestMethod]
        public void DeepZoomOneTalkWithSpaceInPathName()
        {
            /// Attemt to deep zoom one talk
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var meeting = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            JPEGRender rend = new JPEGRender();
            var talkjpegs = rend.RenderMeeting(meeting);

            DeepZoomBuilder bld = new DeepZoomBuilder();
            var talks = from s in meeting.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL != ""
                        select t;

            var atalk = talks.First();

            bld.BuildDirectory = Path.GetTempPath() + "\\Bogus Path";
            FileInfo infoFile = bld.RenderTalk("TalkTest", talkjpegs[atalk]);
            Assert.IsTrue(infoFile.Exists, "Output Scene info file does not exist!");
        }

        [TestMethod]
        public void DeepZoomOneMeeting()
        {
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var meeting = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            JPEGRender rend = new JPEGRender();
            var talkjpegs = rend.RenderMeeting(meeting);

            DeepZoomBuilder bld = new DeepZoomBuilder();

            DirectoryInfo dir = bld.RenderMeeting(meeting, talkjpegs);

            Assert.IsTrue(dir.Exists, "Output directory does not exist!");
            Assert.IsTrue(File.Exists(dir.FullName + "\\items.bin"), "Binary file for items does not exist!");
            Assert.IsTrue(File.Exists(dir.FullName + "\\layout.bin"), "Layout file for items does not exist!");
            Assert.IsTrue(File.Exists(dir.FullName + "\\items.xml"), "XML file for items does not exist!");
            Assert.IsTrue(File.Exists(dir.FullName + "\\layout.xml"), "XML Layout file for items does not exist!");

            /// Check out the items guy and make sure they make some sense.
            Collection c = DTBuilderLib.BinaryIO.ItemsFileIO.Load(new FileInfo(dir.FullName + "\\items.bin"));
            Assert.IsTrue(c.ItemCount == 28, "Wrong number of total slides!");
            Assert.IsTrue(c.PageFormat == "\0\0\0\0\0\0ð?", "Incorrect page format");

            Assert.IsTrue(c.Items != null && c.Items.Length > 0 && c.Items[0] != null && c.Items[0].Item != null, "Items tree not created correctly");
            int count = 0;
            foreach (var slide in c.Items[0].Item)
            {
                Assert.IsTrue(slide.Id == count, "Item ID number is not correct!");
                Assert.IsTrue(slide.Thumb == count, "Item Thumb pointer is not right either");
                Assert.IsTrue(File.Exists(dir.FullName + "\\" + slide.Init), "Could not find slide file!");
                count += 1;
            }

            Assert.IsTrue(c.Thumbnails != null && c.Thumbnails.Length > 0 && c.Thumbnails[0] != null && c.Thumbnails[0].Thumbnail != null, "Thumnail tree not created correctly");
            count = 0;
            foreach (var thumb in c.Thumbnails[0].Thumbnail)
            {
                Assert.IsTrue(thumb.Id == count, "Thumb ID is not correct");
                count += 1;
            }
        }

#endif
    }
}
